package com.blog.service;

import com.blog.entity.Article;
import com.blog.entity.User;
import com.blog.repository.ArticleRepository;
import com.blog.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class ArticleService {
  @Autowired
  private ArticleRepository articleRepository;

  @Autowired
  private UserRepository userRepository;

  @Transactional
  public Article createArticle(Article article, Long userId) {
    User user = userRepository.findById(userId)
        .orElseThrow(() -> new RuntimeException("User not found"));
    article.setUser(user);
    return articleRepository.save(article);
  }

  @Transactional(readOnly = true)
  public Page<Article> getUserArticles(Long userId, Pageable pageable) {
    return articleRepository.findAll(pageable);
  }

  @Transactional
  public Article updateArticle(Long id, Article article) {
    Article existingArticle = articleRepository.findById(id)
        .orElseThrow(() -> new RuntimeException("Article not found"));
    existingArticle.setTitle(article.getTitle());
    existingArticle.setContent(article.getContent());
    existingArticle.setCategory(article.getCategory());
    existingArticle.setTags(article.getTags());
    return articleRepository.save(existingArticle);
  }

  @Transactional
  public void deleteArticle(Long id) {
    articleRepository.deleteById(id);
  }

  @Transactional(readOnly = true)
  public Article getArticle(Long id) {
    return articleRepository.findById(id)
        .orElseThrow(() -> new RuntimeException("Article not found"));
  }

  @Transactional(readOnly = true)
  public Page<Article> searchArticles(String keyword, Pageable pageable) {
    return articleRepository.searchArticles(keyword, pageable);
  }

  @Transactional(readOnly = true)
  public Page<Article> getArticlesByCategory(Long categoryId, Pageable pageable) {
    return articleRepository.findByCategoryId(categoryId, pageable);
  }

  @Transactional(readOnly = true)
  public Page<Article> getArticlesByTag(Long tagId, Pageable pageable) {
    return articleRepository.findByTagId(tagId, pageable);
  }

  @Transactional(readOnly = true)
  public Page<Article> getMostViewedArticles(Pageable pageable) {
    return articleRepository.findMostViewed(pageable);
  }

  @Transactional(readOnly = true)
  public Page<Article> getMostLikedArticles(Pageable pageable) {
    return articleRepository.findMostLiked(pageable);
  }

  @Transactional
  public void incrementViewCount(Long articleId) {
    Article article = getArticle(articleId);
    Integer currentViews = article.getViewCount();
    if (currentViews == null) {
      currentViews = 0;
    }
    article.setViewCount(currentViews + 1);
    articleRepository.save(article);
  }

  @Transactional
  public void incrementLikeCount(Long articleId) {
    Article article = getArticle(articleId);
    Integer currentLikes = article.getLikeCount();
    if (currentLikes == null) {
      currentLikes = 0;
    }
    article.setLikeCount(currentLikes + 1);
    articleRepository.save(article);
  }
}
